package com.qiyu.tech.task.future;

import javax.management.RuntimeErrorException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeoutException;

/**
 * @Author idea
 * @Date created in 2:20 下午 2020/11/30
 */
public class FutureTask<T> implements FutureData<T> {

    private RealData<T> realData;
    private static boolean isReady;
    private long timeOut;
    private static Long DEFAULT_TIME_OUT = 10000L;

    public <T> FutureTask(CallAbleTask<T> callAbleTask) {
        this.buildFutureTask(callAbleTask, DEFAULT_TIME_OUT);
    }

    public <T> FutureTask(CallAbleTask<T> callAbleTask, long timeOut) {
        this.buildFutureTask(callAbleTask, timeOut);
    }

    public synchronized <T> void buildFutureTask(CallAbleTask<T> callAbleTask, long timeOut) {
        isReady = false;
        this.timeOut = timeOut;
        new Thread() {
            @Override
            public void run() {
                realData = new RealData(callAbleTask);
                isReady = true;
            }
        }.start();
    }


    @Override
    public synchronized T get() {
        long beginTime = System.currentTimeMillis();
        while (!isReady) {
            long waitTimeCount = System.currentTimeMillis() - beginTime;
            if ((waitTimeCount) > DEFAULT_TIME_OUT) {
                throw new RuntimeErrorException(new Error("timeout exit , times count is " + (waitTimeCount)));
            }
        }
        return realData.getResult();
    }
}
